#!/bin/bash
# 智能家居代理系统启动脚本 (Linux/macOS)
# Smart Home Agent System Startup Script (Linux/macOS)
#
# 架构设计：
#   - 环境检查模块：统一检查所有运行环境
#   - 配置管理模块：集中处理配置文件读取
#   - 服务管理模块：统一启动/停止服务
#   - 工具函数模块：提供可复用的通用功能

# ========================================
# 初始化设置
# ========================================
set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
GRAY='\033[0;90m'
NC='\033[0m'

# 全局变量
declare -A CONFIG
declare -a PIDS
PROJECT_ROOT=""

# ========================================
# 工具函数模块
# ========================================
print_section() {
    echo
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}$1${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo
}

print_step() {
    echo -e "${YELLOW}$1${NC}"
    echo -e "${YELLOW}$2${NC}"
    echo
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_info() {
    echo -e "${GRAY}  $1${NC}"
}

# ========================================
# 环境检查模块 - 统一检查所有必要的运行环境
# ========================================
check_command() {
    local cmd=$1
    local name=$2
    local hint=$3
    
    if ! command -v "$cmd" &> /dev/null; then
        print_error "错误: 未找到 $name"
        print_error "Error: $name not found"
        echo -e "${YELLOW}  $hint${NC}"
        return 1
    fi
    
    local version=$("$cmd" --version 2>&1 | head -1)
    print_success "$name: $version"
    return 0
}

check_environment() {
    print_step "检查运行环境..." "Checking runtime environment..."
    
    local all_passed=1
    
    check_command "python3" "Python" "请安装 Python 3.8+ / Please install Python 3.8+" || all_passed=0
    check_command "node" "Node.js" "请安装 Node.js 16+ / Please install Node.js 16+" || all_passed=0
    check_command "pnpm" "pnpm" "请运行: npm install -g pnpm" || all_passed=0
    check_command "uv" "uv" "请运行: pip install uv 或访问 https://docs.astral.sh/uv/" || all_passed=0
    
    echo
    
    if [ $all_passed -eq 0 ]; then
        exit 1
    fi
}

# ========================================
# 项目定位模块 - 自动定位项目根目录
# ========================================
find_project_root() {
    print_step "定位项目根目录..." "Locating project root directory..."
    
    local paths=("." ".." "../..")
    
    for path in "${paths[@]}"; do
        if [ -f "$path/config.yaml" ]; then
            cd "$path" || exit 1
            PROJECT_ROOT=$(pwd)
            print_success "配置文件已找到: $PROJECT_ROOT"
            print_success "Configuration file found: $PROJECT_ROOT"
            return 0
        fi
    done
    
    print_error "错误: 未找到配置文件 config.yaml"
    print_error "Error: Configuration file config.yaml not found"
    print_error "当前目录: $PWD"
    exit 1
}

# ========================================
# 配置管理模块 - 集中处理配置读取和默认值
# ========================================
read_yaml_port() {
    local pattern=$1
    local default=$2
    
    local port=$(grep -E "$pattern" config.yaml | head -1 | sed 's/.*port: *\([0-9]*\).*/\1/')
    echo "${port:-$default}"
}

initialize_config() {
    print_step "读取配置文件..." "Reading configuration file..."
    
    # 定义配置映射：pattern|key|default
    local configs=(
        "backend:.*python:.*port:|BackendPort|3000"
        "frontend:.*dev_server:.*port:|FrontendPort|1420"
        "conductor:.*port:|ConductorPort|12000"
        "air_conditioner:.*port:|AirCondPort|12001"
        "air_cleaner:.*port:|AirCleanPort|12002"
        "bedside_lamp:.*port:|BedsideLampPort|12004"
    )
    
    for config_line in "${configs[@]}"; do
        IFS='|' read -r pattern key default <<< "$config_line"
        CONFIG[$key]=$(read_yaml_port "$pattern" "$default")
    done
    
    print_success "配置读取完成"
    print_info "后端端口 / Backend Port: ${CONFIG[BackendPort]}"
    print_info "前端端口 / Frontend Port: ${CONFIG[FrontendPort]}"
    print_info "Conductor端口: ${CONFIG[ConductorPort]}"
    echo
}

# ========================================
# 目录准备模块 - 创建必要的目录
# ========================================
initialize_directories() {
    mkdir -p logs temp
}

# ========================================
# 环境准备模块 - Python虚拟环境和依赖
# ========================================
initialize_python_environment() {
    print_step "检查 Python 虚拟环境..." "Checking Python virtual environment..."
    
    if [ ! -d ".venv" ]; then
        print_error "虚拟环境不存在，正在创建..."
        print_error "Virtual environment not found, creating..."
        print_info "执行: uv venv"
        uv venv
        
        if [ $? -ne 0 ]; then
            print_error "虚拟环境创建失败！"
            print_error "Virtual environment creation failed!"
            exit 1
        fi
        print_success "虚拟环境创建完成"
    else
        print_success "虚拟环境已存在"
    fi
    
    echo
    print_step "安装 Python 依赖..." "Installing Python dependencies..."
    print_info "执行: uv sync"
    uv sync
    
    if [ $? -ne 0 ]; then
        print_error "Python 依赖安装失败！"
        print_error "Python dependencies installation failed!"
        exit 1
    fi
    print_success "Python 依赖已安装"
}

initialize_frontend_dependencies() {
    print_step "检查前端依赖..." "Checking frontend dependencies..."
    
    if [ ! -d "app/node_modules" ]; then
        print_error "前端依赖未安装，正在安装..."
        print_error "Frontend dependencies not installed, installing..."
        echo
        
        cd app || exit 1
        print_info "执行: pnpm install"
        pnpm install
        
        if [ $? -ne 0 ]; then
            cd ..
            print_error "依赖安装失败！"
            print_error "Dependency installation failed!"
            exit 1
        fi
        cd ..
        print_success "依赖安装完成"
    else
        print_success "前端依赖已安装"
    fi
    echo
}

# ========================================
# 服务启动模块 - 统一管理所有服务启动
# ========================================
start_service() {
    local index=$1
    local name_cn=$2
    local name_en=$3
    local directory=$4
    local command=$5
    local port_key=$6
    local delay=$7
    
    local port=${CONFIG[$port_key]}
    
    echo -e "${CYAN}[$index/6] 启动$name_cn (端口 $port)...${NC}"
    echo -e "${CYAN}[$index/6] Starting $name_en (Port $port)...${NC}"
    
    cd "$PROJECT_ROOT/$directory" || exit 1
    
    # 启动服务并重定向输出到日志
    eval "$command" >> "$PROJECT_ROOT/logs/${name_en// /_}.log" 2>&1 &
    local pid=$!
    PIDS+=($pid)
    
    cd "$PROJECT_ROOT" || exit 1
    sleep "$delay"
    
    print_success "$name_cn 已启动"
    print_success "$name_en started"
    echo
}

start_all_services() {
    print_section "正在启动 Moss AI 本地开发环境...
Starting Moss AI Local Development Environment..."
    
    # 定义服务配置：index|name_cn|name_en|directory|command|port_key|delay
    local services=(
        "1|后端服务|Backend Service|app/backend-python|uv run .|BackendPort|3"
        "2|总管理代理|Conductor Agent|agents/conductor_agent|uv run .|ConductorPort|3"
        "3|空调代理|Air Conditioner Agent|agents/air_conditioner_agent|uv run .|AirCondPort|2"
        "4|空气净化器|Air Cleaner Agent|agents/air_cleaner_agent|uv run .|AirCleanPort|2"
        "5|床头灯代理|Bedside Lamp Agent|agents/bedside_lamp_agent|uv run .|BedsideLampPort|2"
        "6|前端开发服务器|Frontend Dev Server|app|pnpm dev|FrontendPort|3"
    )
    
    for service_config in "${services[@]}"; do
        IFS='|' read -r idx name_cn name_en dir cmd port_key delay <<< "$service_config"
        start_service "$idx" "$name_cn" "$name_en" "$dir" "$cmd" "$port_key" "$delay"
    done
    
    print_info "所有服务窗口正在后台运行"
    print_info "All services are running in background"
    echo
}

# ========================================
# 信息显示模块 - 显示服务地址和使用说明
# ========================================
show_service_info() {
    print_section "所有服务已启动完成！
All services started successfully!"
    
    echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║                    服务地址 / Service URLs                  ║${NC}"
    echo -e "${CYAN}╠════════════════════════════════════════════════════════════╣${NC}"
    echo -e "${CYAN}║                                                            ║${NC}"
    echo -e "${CYAN}║  【前端应用 / Frontend】                                     ║${NC}"
    echo -e "${YELLOW}║    http://localhost:${CONFIG[FrontendPort]}${NC}"
    echo -e "${CYAN}║    ★ 请在浏览器中打开此地址使用应用                           ║${NC}"
    echo -e "${CYAN}║                                                            ║${NC}"
    echo -e "${CYAN}║  【后端服务 / Backend】                                      ║${NC}"
    echo -e "${NC}║    http://localhost:${CONFIG[BackendPort]}${NC}"
    echo -e "${CYAN}║                                                            ║${NC}"
    echo -e "${CYAN}║  【智能代理 / Agents】                                       ║${NC}"
    echo -e "${NC}║    总管理代理 / Conductor:      http://localhost:${CONFIG[ConductorPort]}${NC}"
    echo -e "${NC}║    空调代理 / Air Conditioner:  http://localhost:${CONFIG[AirCondPort]}${NC}"
    echo -e "${NC}║    空气净化器 / Air Cleaner:    http://localhost:${CONFIG[AirCleanPort]}${NC}"
    echo -e "${NC}║    床头灯 / Bedside Lamp:       http://localhost:${CONFIG[BedsideLampPort]}${NC}"
    echo -e "${CYAN}║                                                            ║${NC}"
    echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
    echo
}

# ========================================
# 服务停止模块 - 统一停止所有服务
# ========================================
stop_all_services() {
    echo
    print_step "正在停止所有服务..." "Stopping all services..."
    
    # 停止所有启动的进程
    for pid in "${PIDS[@]}"; do
        if kill -0 "$pid" 2>/dev/null; then
            print_info "停止进程 PID: $pid"
            kill "$pid" 2>/dev/null || true
        fi
    done
    
    # 停止端口占用的进程
    local ports=(
        "${CONFIG[FrontendPort]}" 
        "${CONFIG[BackendPort]}" 
        "${CONFIG[ConductorPort]}"
        "${CONFIG[AirCondPort]}"
        "${CONFIG[AirCleanPort]}"
        "${CONFIG[BedsideLampPort]}"
    )
    
    for port in "${ports[@]}"; do
        # Linux
        if command -v lsof &> /dev/null; then
            local pid=$(lsof -ti:"$port" 2>/dev/null || true)
            if [ -n "$pid" ]; then
                print_info "停止端口 $port 的进程 (PID: $pid)"
                kill "$pid" 2>/dev/null || true
            fi
        # macOS alternative
        elif command -v netstat &> /dev/null; then
            local pid=$(netstat -vanp tcp 2>/dev/null | grep "\.$port " | awk '{print $9}' | head -1)
            if [ -n "$pid" ]; then
                print_info "停止端口 $port 的进程 (PID: $pid)"
                kill "$pid" 2>/dev/null || true
            fi
        fi
    done
    
    print_success "所有服务已停止"
    print_success "All services stopped"
}

# ========================================
# 信号处理 - 捕获 Ctrl+C 等中断信号
# ========================================
cleanup() {
    stop_all_services
    exit 0
}

trap cleanup SIGINT SIGTERM

# ========================================
# 主流程
# ========================================
main() {
    clear
    print_section "智能家居代理系统启动脚本
Smart Home Agent System Startup Script"
    
    check_environment
    find_project_root
    initialize_config
    initialize_directories
    initialize_python_environment
    initialize_frontend_dependencies
    start_all_services
    show_service_info
    
    echo -e "${YELLOW}提示：按 Ctrl+C 停止所有服务并退出${NC}"
    echo -e "${YELLOW}Note: Press Ctrl+C to stop all services and exit${NC}"
    echo
    
    # 等待用户中断
    wait
}

# 运行主程序
main
